<template>
  <h1 class="m-v-20">响应式基础</h1>

  <h3 class="m-v-10">声明响应式状态</h3>
  <div>响应式的实质Proxy</div>
  <div>reactive复杂数据类型响应式----<span ref="count">{{state.count}}</span> <button @click="add">加一</button></div>

  <h3 class="m-v-10">script setup</h3>
  <div>简化代码，顶层的导入和变量的声明可在同一组件模版中直接使用，可以理解为同一作用域中</div>

  <h3 class="m-v-10">DOM更新时机</h3>
  <div>访问更新后的DOM--nextTick(()=>{})</div>

  <h3 class="m-v-10">深层响应性</h3>
  <div>在vue3中状态都是默认深层响应式的，深层的改动也能被检测到</div>
  <div>两层嵌套响应{{state.deepCount.count}},<button @click="deepAdd">深层加一</button></div>

  <h3 class="m-v-10">响应式代理VS原始对象</h3>
  <div>
    reactive返回的是一个演示对象Proxy，它和原始对象是不想等的
    <br>
    const raw ={}<button @click="changeRaw">更改原始对象</button>{{raw.count}}
    <br>
    const proxy = reactive(raw) <button @click="changeProxy">更改代理对象</button>{{proxy.count}}
    <br />
    raw!==proxy<br />
    只有代理对象（proxy）是响应式的，更改原始对象(raw)不会触发更新，因此，使用Vue的响应式系统的最佳实践式 <strong>仅使用你声明对象的代理版本</strong>
    <br>
    修改任何一个两个可以同时改变但是，raw不是响应式的，只有proxy是响应式的
    <br>
    对一个原始对象调用reactive会总是返回同样的代理对象，reactive(raw) ===reactive(raw),对一个已经存在的代理对象调用reactive会返回它本身，reactive(proxy)===proxy
    <br>
    这个规则对嵌套对象同样适用
  </div>

  <h3 class="m-v-10">reactive对象的局限性</h3>
  <div>
    1. 对简单数据类型无效<br>
    2. 因为Proxy响应式系统是通过属性的访问进行追踪的，因此我们必须始终保持对该响应式对象的相同引用，不可以随意的替换，不然会丢失对初始引用的响应性连接<br>
    3. 赋值或者解构到别的变量或者作为函数的参数时，都会失去响应<br>
    <button @click="add">改变响应式对象的值</button>，{{state.count}}
    <br>
    赋值的变量{{count1}},解构出来的值{{count2}}
  </div>

  <h3 class="m-v-10">ref()定义响应式变量</h3>
  <div>
    1. ref将传入参数的值包装为一个带有value属性的ref对象，cosnt count = ref(0)//count.value=0--{{countRef}}
  </div>

  <h3 class="m-v-10">ref在模版中的解包</h3>
  <div>
    1. 自动替换成.value ----- {{countRef}}<br>
    2. 仅仅当ref是模版上下文的顶层属性时才适用自动解包，{{object.foo+1}},object.foo是一个ref对象<br>
    3.解构出来的foo同样具有响应式{{foo+1}}
  </div>

  <h3 class="m-v-10">ref在响应式对象中的解包</h3>
  <div>
    1. ref嵌套在一个响应对象中，作为属性被访问或更改时会自动解包---{{stateReactive.countRef}}<br>
    2. 新的ref会替换掉旧的ref
  </div>
</template>

<script setup>
import { nextTick, reactive, ref } from 'vue'
const state = reactive({
  count: 0,
  deepCount: {
    count: 0
  }
})
const newCount = ref(0)

function add() {
  state.count++
  nextTick(() => {
    //访问更新后的DOM
  })
}

function deepAdd() {
  state.deepCount.count++
}

const raw = {
  count: 0
}
const proxy = reactive(raw)
console.log(raw === proxy);

function changeRaw() {
  raw.count++
  console.log(raw, proxy);
}

function changeProxy() {
  proxy.count++
  console.log(raw, proxy);
}

console.log(reactive(raw) === proxy)
console.log(reactive(proxy) === proxy)

const count1 = state.count
const { count: count2 } = state

const countRef = ref(0)


const object = { foo: ref(1) }

const { foo } = object

const stateReactive = reactive({
  countRef
})

console.log(stateReactive.countRef);



</script>

<style lang="scss" scoped>
</style>